package com.bangcommunity.bbframe.fdfs.connection;

import com.bangcommunity.bbframe.fdfs.FdfsSourceInputStream;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.DownloadCallback;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.UploadCallback;

import java.io.IOException;

/**
 * @author tanghc
 * @date 18/6/22
 */
public interface StorageConnection extends FdfsSocketConnection {

    /**
     * upload file to storage server
     *
     * @param cmd
     *            the command code
     * @param groupName
     *            the group name to upload file to, can be empty
     * @param masterFilename
     *            the master file name to generate the slave file
     * @param prefixName
     *            the prefix name to generate the slave file
     * @param fileExtName
     *            file ext name, do not include dot(.)
     * @param fileSize
     *            the file size
     * @param callback
     *            the write data callback object
     * @return 2 elements string array if success:<br>
     *         <ul>
     *         <li>results[0]: the group name to store the file</li>
     *         </ul>
     *         <ul>
     *         <li>results[1]: the new created filename</li>
     *         </ul>
     *         return null if fail
     */
    String[] doUploadFile(byte cmd, String groupName, String masterFilename, String prefixName,
                          String fileExtName, long fileSize, UploadCallback callback) throws IOException, MyException;

    /**
     * modify appender file to storage server
     *
     * @param groupName
     *            the group name of appender file
     * @param fileId
     *            the appender filename
     * @param fileOffset
     *            the offset of appender file
     * @param modifySize
     *            the modify size
     * @param callback
     *            the write data callback object
     * @return 0 for success, other for fail
     */
    int doModifyFile(String groupName, String fileId, long fileOffset, long modifySize,
                     UploadCallback callback) throws IOException, MyException;

    /**
     * append file to storage server
     *
     * @param groupName
     *            the group name of appender file
     * @param fileId
     *            the appender filename
     * @param fileSize
     *            the file size
     * @param callback
     *            the write data callback object
     * @return 0 for success, other for fail
     */
    int doAppendFile(String groupName, String fileId, long fileSize, UploadCallback callback)
            throws IOException, MyException;

    /**
     * download file from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            filename on storage server
     * @param fileOffset
     *            the start offset of the file
     * @param downloadBytes
     *            download bytes, 0 for remain bytes from offset
     * @return file content/buff, return null if fail
     */
    byte[] downloadFile(String groupName, String fileId, long fileOffset, long downloadBytes)
            throws IOException, MyException;

    /**
     * download file from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param remoteFilename
     *            filename on storage server
     * @param fileOffset
     *            the start offset of the file
     * @param downloadBytes
     *            download bytes, 0 for remain bytes from offset
     * @param callback
     *            call callback.recv() when data arrive
     * @return 0 success, return none zero errno if fail
     */
    int downloadFile(String groupName, String remoteFilename, long fileOffset, long downloadBytes,
                     DownloadCallback callback) throws IOException, MyException;

    FdfsSourceInputStream getFdfsSourceInputStream(String groupName, String remoteFilename, long fileOffset, long downloadBytes) throws IOException, MyException;

    /**
     * truncate appender file from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            the appender filename
     * @param truncatedFileSize
     *            truncated file size
     * @return 0 for success, none zero for fail (error code)
     */
    int truncateFile(String groupName, String fileId, long truncatedFileSize) throws IOException, MyException;

    /**
     * delete file from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            filename on storage server
     * @return 0 for success, none zero for fail (error code)
     */
    int deleteFile(String groupName, String fileId) throws IOException, MyException;

    /**
     * get all metadata items from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            filename on storage server
     * @return meta info array, return null if fail
     */
    NameValuePair[] getMetadata(String groupName, String fileId) throws IOException, MyException;

    /**
     * set metadata items to storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            filename on storage server
     * @param metaList
     *            meta item array
     * @param opFlag
     *            flag, can be one of following values: <br>
     *            <ul>
     *            <li>ProtoCommon.STORAGE_SET_METADATA_FLAG_OVERWRITE: overwrite all old metadata
     *            items</li>
     *            </ul>
     *            <ul>
     *            <li>ProtoCommon.STORAGE_SET_METADATA_FLAG_MERGE: merge, insert when the metadata
     *            item not exist, otherwise update it</li>
     *            </ul>
     * @return 0 for success, !=0 fail (error code)
     */
    int setMetadata(String groupName, String fileId, NameValuePair[] metaList, byte opFlag)
            throws IOException, MyException;

    /**
     * get file info decoded from the filename, fetch from the storage if necessary
     *
     * @param groupName
     *            the group name
     * @param fileId
     *            the filename
     * @return FileInfo object for success, return null for fail
     */
    FileInfo getFileInfo(String groupName, String fileId) throws IOException, MyException;

    /**
     * get file info from storage server
     *
     * @param groupName
     *            the group name of storage server
     * @param fileId
     *            filename on storage server
     * @return FileInfo object for success, return null for fail
     */
    FileInfo queryFileInfo(String groupName, String fileId) throws IOException, MyException;
}
